#ifndef HLP2P_H
#define HLP2P_H

#ifdef __cplusplus
#if __cplusplus
extern "C"
{
#endif
#endif /* __cplusplus */

    /********=======================下面是错误码========================================***********/

#define HL_ERROR_SUCCESSFUL 0                           /**成功操作**/
#define HL_ERROR_NO_INITIALIZED -1                      /**还未初始化**/
#define HL_ERROR_ALREADY_INITIALIZED -2                 /**已经初始化了,不需要再初始化**/
#define HL_ERROR_TIME_OUT -3                            /**操作超时,应该继续重复**/
#define HL_ERROR_INVALID_ID -4                          /**无效ID**/
#define HL_ERROR_INVALID_PARAMETER -5                   /**无效参数**/
#define HL_ERROR_DEVICE_NOT_ONLINE -6                   /**设备不在线**/
#define HL_ERROR_FAIL_TO_RESOLVE_NAME -7                /**域名解析失败**/
#define HL_ERROR_INVALID_PREFIX -8                      /**无效前缀**/
#define HL_ERROR_ID_OUT_OF_DATE -9                      /**ID过期,被加入黑名单**/
#define HL_ERROR_NO_RELAY_SERVER_AVAILABLE -10          /**没有可用的转发服务器**/
#define HL_ERROR_INVALID_SESSION_HANDLE -11             /**无效session,连接已经断开了**/
#define HL_ERROR_SESSION_CLOSE_REMOTE -12               /**远端关闭了session,连接已经断开了**/
#define HL_ERROR_SESSION_CLOSE_TIMEOUT -13              /**底层⼼跳超时,需要重新连接,连接已经断开了**/
#define HL_ERROR_SESSION_CLOSE_CALLED -14               /**我方关闭了session,连接已经断开了**/
#define HL_ERROR_REMOTE_SITE_BUFF_FULL -15              /**对方接收buff满了**/
#define HL_ERROR_USER_LISTEN_BREAK -16                  /**主动打断监听**/
#define HL_ERROR_MAX_SESSION -17                        /**session 超出连接数**/
#define HL_ERROR_USER_CONNECT_BREAK -19                 /**主动打断连接**/
#define HL_ERROR_SESSION_CLOSED_INSUFFICIENT_MEMORY -20 /**因内存资源不足,关闭连接,上层需要考虑重启设备**/
#define HL_ERROR_INVALID_LICENSE -21                    /**无效LICENSE**/
#define HL_ERROR_FAIL_TO_CREATE_THREAD -22              /** 创建线程失败,一般都是资源不足,上层需要考虑重启设备**/

//--------------------------
#define HL_ERROR_FAIL_TO_ALLOCATE_MEMORY -100 /** 因内存资源不足分配失败,上层需要考虑重启设备**/
#define HL_ERROR_INVALID_INIT_STRING -101     /**无效加密字串**/

#define HL_ERROR_BUFF_FULL_LOCAL -102 /**我方发送buff满了,应该延时10ms再重试**/
#define HL_ERROR_BUFF_LEN -103        /**保存数据的上层buff太小**/
#define HL_ERROR_DATA_LEN_ZERO -104   /**发送的数据必须大于0**/
#define HL_ERROR_DATA_MAX_2M -105     /**发送的数据最大不超过2M**/
#define HL_ERROR_DATA_INVALID -106    /**无效数据**/

#define HL_ERROR_NOT_AVAILABLE -107   /**库没有开放该功能**/
#define HL_ERROR_OPEN_FILE_FAIL -108  /**打开文件失败**/
#define HL_ERROR_PATH_TOO_LENGTH -109 /**文件路径太长**/

#define HL_ERROR_IS_P2P_CALLBACK_DATA -110      /**你开启了库回调数据,不需要你去读数据**/
#define HL_ERROR_IS_P2P_LISTEN_APP_CONNECT -111 /**你开启了库监听APP连接,不需要你去监听连接**/

#define HL_ERROR_CLOUD_DOMAIN_PARSE_FAIL -112 /**云端服务器域名解析失败**/
#define HL_ERROR_CLOUD_CONNECT_SVR_FAIL -113  /**云服务器连接失败**/

//-------------------------
#define HL_ERROR_CODEC_FAIL -114                /**音视频编解码/拍照/录像等失败,可以继续重来**/
#define HL_ERROR_CODEC_ID_INVALID -115          /**cid无效**/
#define HL_ERROR_CODEC_NOT_I_FRAME -116         /**需要i帧,等待i帧再往下发**/
#define HL_ERROR_CODEC_DEST_BUFF_TOO_SMALL -117 /**上层保存解码或编码后数据的buff太小(1,如果是视频,会返回当前视频的最新宽高,用于上层创建更大buff的依据;2,如果是音频,那就上层自己直接创建更大一点的buff)**/

#define HL_ERROR_FAIL -118                  /**失败,看cb_error()回调信息**/
#define HL_ERROR_MAX_SESSION_REMOTE -119    /**对方的连接数量已满,不能再连接了**/
#define HL_ERROR_CREATE_SOCKET_FAIL -120    /**创建socket失败,需要重启一下设备恢复**/
#define HL_ERROR_CREATE_BIND_PORT_FAIL -121 /**端口绑定失败**/
#define HL_ERROR_DID_UNSUPPORT_WEBRTC -122  /**这个did不支持webrtc,请使用支持webrtc的did**/
#define HL_ERROR_WEBRTC_LIVE_INVALID -123   /**直播推送无效,应该停止推送**/

    /********=======================日志类型========================================***********/

#define HL_LOG_TYPE_MGT 1    /**库心跳日志**/
#define HL_LOG_TYPE_SESS 2   /**连接日志**/
#define HL_LOG_TYPE_CGT 4    /**发送数据日志**/
#define HL_LOG_TYPE_WEBRTC 8 /**webrtc相关日志**/

    /********=======================下面是结构体========================================***********/
    /**设备监听App连接的模式**/
    typedef enum hl_listen_mode
    {
        HL_LISTEN_MODE_LAN,            /**只监听局域网的App连接(如果前面调用了库监听就会失效)**/
        HL_LISTEN_MODE_WAN,            /**同时监听局域网和外网App连接(如果前面调用了库监听就会失效)**/
        HL_LISTEN_MODE_LAN_LIB_LISTEN, /**由库来监听,只监听局域网的App连接,调用Listen函数后会马上返回**/
        HL_LISTEN_MODE_WAN_LIB_LISTEN, /**由库来监听,同时监听局域网和外网App连接,调用Listen函数后会马上返回**/
        HL_LISTEN_MODE_LIB_NONE,       /**停止库监听**/
    } hl_listen_mode;

    /**App连接设备的模式**/
    typedef enum hl_connect_mode
    {
        HL_CONNECT_MODE_ALL,         /**先Lan,P2P,再SRelay(服务器转发),再DRelay(设备转发),再PRelay(平台转发)**/
        HL_CONNECT_MODE_LAN_ONLY,    /**只通过Lan连接设备**/
        HL_CONNECT_MODE_P2P,         /**先Lan,P2P,再DRelay,再PRelay**/
        HL_CONNECT_MODE_SRELAY,      /**先Lan,再SRelay**/
        HL_CONNECT_MODE_SRELAY_ONLY, /**只通过SRelay连接设备**/
        HL_CONNECT_MODE_FAST,        /**快速连接,会同时进行Lan,P2P,SRelay连接,谁先成功用谁,最后如果Lan或者P2P能通,就会用这两个之一**/
        HL_CONNECT_MODE_TCP,         /**只进行TCP服务器转发连接**/
        HL_CONNECT_MODE_WAKEUP,      /**只向设备发起唤醒指令,不会连接设备**/
    } hl_connect_mode;

    /**App与设备之间的连接状态**/
    typedef enum hl_connect_status
    {
        HL_CONNECT_STATUS_UNKNOW,               /**连接状态未知**/
        HL_CONNECT_STATUS_ONLINE_LAN,           /**局域网在线**/
        HL_CONNECT_STATUS_ONLINE_P2P,           /**P2P在线**/
        HL_CONNECT_STATUS_ONLINE_DEV_RELAY,     /**设备转发在线**/
        HL_CONNECT_STATUS_ONLINE_PLAT_RELAY,    /**平台转发在线**/
        HL_CONNECT_STATUS_ONLINE_SVR_RELAY,     /**服务器转发在线**/
        HL_CONNECT_STATUS_ONLINE_SVR_RELAY_TCP, /**服务器TCP转发在线**/
    } hl_connect_status;

    /**App查询设备当前在线状态**/
    typedef struct hl_dev_state
    {
        long end_time_wk; /**设备最后低功耗在线时间(UTC时间,单位是秒)**/
        long end_time;    /**设备最后心跳时间(UTC时间,单位是秒)**/
        char status;      /**当前状态：0-设备离线,1-在线已休眠,2-在线未休眠**/
        char mode;        /**当status==2时,再判断mode的值：深休眠、浅休眠或其他(该值设备透传的,app可以和设备端约定该值)**/
        char is_tcp;      /**如果设备在线,是否为tcp心跳：0-否,1-是**/
    } hl_dev_state;

    /**设备端查询与p2p服务器心跳状态**/
    typedef struct hl_svr_login
    {
        long udp_send_time; /**最近一次udp心跳时间**/
        long tcp_conn_time; /**最近一次tcp连接的时间**/

        long alive_ack_time; /**最后一次p2p服务器回心跳的时间,utc秒值**/
        char login;          /**登录p2p服务器是否成功,0-未登录成功,1-登录成功**/
        char is_tcp_alive;   /**是否为tcp心跳,0-udp,1-tcp**/
        char udp_arrive;     /**udp心跳达到3个p2p服务器的情况,以位表示3个p2p服务器,第0位为第一个服务器,对应位为1表示到达,0表示为未到**/
        char udp_alive_cnt;  /**向服务器发起了几次udp心跳**/
        char alive_mode;     /**表示心跳模式：0-多个服务器心跳,1-设备单服务器心跳,2-服务器强制单服务器心跳,3-心率不整,强制TCP心跳,4-服务器强制TCP心跳**/

        char nat; /**网络类型：0-端口限制,1-IP限制,2-对称型,端口变化不大,3-对称型,端口变化特别大(默认是端口限制)**/
    } hl_svr_login;

    /**视频格式**/
    typedef enum hl_video_format
    {
        HL_VIDEO_FMT_H264,
        HL_VIDEO_FMT_H265,
        HL_VIDEO_FMT_MJPG,
    } hl_video_format;

    /**音频格式**/
    typedef enum hl_audio_format
    {
        HL_AUDIO_FMT_AAC,
        HL_AUDIO_FMT_G711_A,
        HL_AUDIO_FMT_G711_U,
        HL_AUDIO_FMT_PCM,
    } hl_audio_format;

    /**webrtc头,放在data数据前**/
    typedef struct hl_webrtc_header
    {
        unsigned int time_sec;     /**音视频帧产生的秒值**/
        unsigned int time_ms : 10; /**音视频帧产生的毫秒值**/
        unsigned int channel : 3;  /**镜头通道,用于多镜头,音频和视频要是相同通道值(0-第一个镜头,1-第二个镜头,以此类推)**/
        unsigned int iframe : 1;   /**是否为I帧**/
    } hl_webrtc_header;

    /**低功耗心跳连接,服务器回复的指令**/
    typedef enum hl_wk_cmd
    {
        HL_WK_CMD_ALIVE_ACK, // 回复心跳ack
        HL_WK_CMD_WAKEUP,    // 唤醒设备
    } hl_wk_cmd;

    /***
     * 注意：非常非常重要
     * 1）请在初始化库之前设置回调
     * 2）请不要在回调函数中做耗时操作,如果是耗时操作,请开子线程对数据进行处理
     * **/
    typedef struct hl_p2p_cb
    {
        /**-----下面是App与Dev都应该监听的回调------**/
        /**
         * 日志回调
         * 请把日志保存到文件中,方便后期排查问题
         *
         * @param type 类型：0-服务器心跳,1-与app连接的日志
         * @param log  日志内容(字符串)
         */
        void (*cb_log)(char type, char *log);

        /**-----下面是App端应该监听的回调------**/
        /**
         * 搜索局域网设备回调
         * 库会搜索5秒时长
         *
         * @param did 设备ID
         * @param end 标志：0-库还在搜索中,1-已经搜索完成
         */
        void (*cb_app_search)(char *did, char end);

        /**
         * 向Dev发送透传数据的结果
         *
         * @param did      设备ID
         * @param status   状态：-6-设备离线,发送失败;-3-发送超时失败;1-发送成功,对方已接收到;2-对方回复透传数据
         * @param qid      发送的唯一ID：上层发送的唯一编码,原值返回
         * @param data     Dev发过来的透传数据,status=2时才有该值
         * @param data_len Dev发过来的数据长度
         */
        void (*cb_app_transfer_data)(char *did, int status, int qid, char *data, int data_len);

        /**
         * 查询设备当前状态回调
         *
         * @param did         设备ID
         * @param status      状态：-3-库中查询超时;0-设备离线;1-在线已休眠; 2-在线
         * @param mode        状态码：当status==2时,设备休眠状态(如：深休眠,浅休眠等,该值双方自行约定)
         * @param end_time    设备最后在线时间(UTC时间,单位是秒)
         * @param end_time_wk 设备最后低功耗心跳在线时间(UTC时间,单位是秒)
         * @param is_tcp      心跳类型：0-udp心跳,1-tcp心跳
         * @param user        上层传入的句柄,原值返回
         */
        void (*cb_app_dev_state)(char *did, char status, char mode, long end_time, long end_time_wk, char is_tcp, void *user);

        /**
         * App异步连接Dev时,连接结果从这里返回
         *
         * @param session       连接时返回的session,上层要保存,在这里对应是哪台设备
         * @param status        状态：>0查看hl_connect_status对应值,<0查看错误码
         * @param user          上层传入的句柄,原值返回(上层可以把连接对象传入)
         */
        void (*cb_app_connect_status)(int session, int status, void *user);

        /**
         * 收到Dev发过来的数据
         * 注意：在初始化库时 is_lib_callback_data=1,才会收到Dev数据时 库主动回调
         *
         * @param session  连接时返回的session,上层要保存,在这里对应是哪台设备
         * @param channel  对应通道的数据
         * @param data     数据内容
         * @param data_len 数据长度
         * @param user     上层传入的句柄,原值返回(上层可以把连接对象传入)
         */
        void (*cb_app_session_data)(int session, char channel, char *data, int data_len, void *user);

        /**
         * 连接链路的当前带宽情况回调
         *
         * @param session 连接时返回的session,上层要保存,在这里对应是哪台设备
         * @param send_bw 当前可发送的带宽(不表示当前发送了这么多数据),可以用来做动态码率的参考依据
         * @param recv_bw 上一秒接收到的带宽
         * @param user    上层传入的句柄,原值返回(上层可以把连接对象传入)
         */
        void (*cb_app_bandwidth)(int session, int send_bw, int recv_bw, void *user);

        /**-----下面是Dev端应该监听的回调------**/
        /**
         * 库建议重启设备回调
         * 当库3分钟无法连接上p2p服务器时,会通知上层建议重启设备,可能是设备端网络出现问题了
         *
         * @param type 暂时不需要关心该值
         */
        void (*cb_dev_reboot_advise)(char type);

        /**
         * 设备与p2p服务器的连接状态回调
         *
         * @param status 状态：0-与服务器未连接,1-与服务器连接成功
         */
        void (*cb_dev_svr_login_status)(char status);

        /**
         * 由上层来解析域名
         * 1）域名解析要放到上层子线程中,不能阻塞我的回调
         * 2）解析成功后调用hl_p2p_set_p2p_domain_ip()把p2p的ip设置给库,转发服务器的域名解析的ip不需要管,但一定要去解析
         *
         * @param p2p_domains   p2p服务器的域名(多个时使用,分隔)
         * @param relay_domains 转发服务器的域名(多个时使用,分隔)
         */
        void (*cb_dev_need_parse_domain)(char *p2p_domains, char *relay_domains);

        /**
         * webrtc回调
         * 收到web端连接设备,调用 hl_p2p_webrtc_push()发送数据
         * 注意：
         * 1）status = 0 表示连接已经关闭了,上层停止发数据就好
         * 2）status = 1 表示有新的连接上来,data里面带了post请求的body数据
         * 3）status = 2 表示收到web端对应通道发来的数据
         *
         * @param wid      唯一ID
         * @param status   状态：0-直播连接关闭,1-直播开始,2-收到web端发来的数据
         * @param channel  通道数：0-命令通道,1-视频通道,2-音频通道,3-数据通道
         * @param data     收到数据
         * @param data_len 数据长度
         */
        void (*cb_dev_webrtc_live)(int wid, char status, char channel, char *data, int data_len);

        /**
         * App发过来透传数据
         *
         * @param aid      这次数据的唯一ID(如果你要回app数据,需要使用这个)
         * @param seq      这次数据的序列号(如果你要回app数据,需要使用这个)
         * @param data     app发过来的数据
         * @param data_len 数据长度
         */
        void (*cb_dev_transfer_data)(int aid, int seq, char *data, int data_len);

        /**
         * App连接过来,或连接状态发生改变
         * 注意：只有设置了库监听app连接,才会有改回调
         *
         * @param session       一次连接的session(上层链表没有就是新连接,如果有就是状态改变)
         * @param status        状态：>0查看hl_connect_status对应值,<0查看错误码
         * @param remote_lan_ip app端的局域网ip
         */
        void (*cb_dev_connect_status)(int session, int status, char *remote_lan_ip);

        /**
         * 收到App发过来的数据
         * 注意：在初始化库时 is_lib_callback_data=1,才会收到App数据时 库主动回调
         *
         * @param session  连接时返回的session,上层要保存,在这里对应是哪台设备
         * @param channel  对应通道的数据
         * @param data     数据内容
         * @param data_len 数据长度
         */
        void (*cb_dev_session_data)(int session, char channel, char *data, int data_len);

        /**
         * 连接链路的当前带宽情况回调
         *
         * @param session  对应的连接
         * @param send_bw  当前可发送的带宽(不表示当前发送了这么多数据),可以用来做动态码率的参考依据
         * @param recv_bw  上一秒接收到的带宽
         */
        void (*cb_dev_bandwidth)(int session, int send_bw, int recv_bw);

        //-----下面是暂时未用------
        void (*cb_cloud_progress)(int code, long total, long pro);   /**下载或上传文件进度回调**/
        void (*cb_cloud_reuslt)(int code, char *data, int data_len); /**http请求结果返回**/
    } hl_p2p_cb;

    /********=======================下面是P2P接口========================================***********/
    /**-----App与Dev端都具备的功能------**/
    /**
     * [设置库日志开关](库默认是关闭的)
     * 请在初始化库之前设置
     *
     * @param type   [in] 日志类型:一个或多个 HL_LOG_TYPE_MGT|HL_LOG_TYPE_SESS
     * @param level  [in] 暂时填0
     * @param open   [in] 0-关闭,1-开启
     *
     * @return 错误码如下：
     * @retval HL_ERROR_SUCCESSFUL
     * @retval HL_ERROR_INVALID_PARAMETER
     */
    int hl_p2p_set_log_level(char type, char level, char open);

    /**
     * [获取库版本号]
     *
     * @return 返回库编译的日志
     * @retval 比如：20250808
     */
    int hl_p2p_get_version(void);

    /**
     * [设置库回调函数]
     * 请在初始化库之前设置
     *
     * @param cb   [in] 回调函数
     *
     * @return 错误码如下：
     * @retval HL_ERROR_SUCCESSFUL
     * @retval HL_ERROR_INVALID_PARAMETER
     */
    int hl_p2p_set_callback(hl_p2p_cb *cb);

    /**
     * [初始化库]
     * 推荐:使用库回调数据,这样数据回调更及时,同时节省上层开线程去读数据
     * 注意:如果是库回调数据,一定不能在回调函数做耗时操作,不然会阻塞库里面的线程
     *
     * @param svr                   [in] 加密字符串
     * @param session_max           [in] 最大连接数(默认与最大值都是800,这个只是数值,设置多少不会增加库内存)
     * @param channel_max           [in] 每个连接最大通道数(默认与最大值都是8,这个只是数值,设置多少不会增加库内存)
     * @param session_alive_sec     [in] 每个连接之间的心跳超时时间,范围：10~20
     * @param is_lib_callback_data  [in] 库回调数据：0-不回调,1-回调(设置库回调数据后,上层不需要去读数据,数据从cb_app_session_data/cb_dev_session_data回调)
     * @param is_one_svr_alive      [in] 是否只向一个服务器保持心跳,这样可以节省服务器带宽,让p2p服务器支持更多的设备
     *
     * @return 错误码如下：
     * @retval HL_ERROR_SUCCESSFUL
     * @retval HL_ERROR_ALREADY_INITIALIZED
     * @retval HL_ERROR_INVALID_INIT_STRING
     * @retval HL_ERROR_FAIL_TO_CREATE_THREAD
     * @retval HL_ERROR_FAIL_TO_ALLOCATE_MEMORY
     * @retval HL_ERROR_FAIL
     */
    int hl_p2p_init(char *svr, int session_max, char channel_max, char session_alive_sec, char is_lib_callback_data, char is_one_svr_alive);

    /**
     * [注销库]
     * 在给主控断电前记得注销库
     * 如果只给主控断网,不需要注销库,这个时候调用hl_p2p_network_ok(0)告诉库没有网络 是比较好的选择
     *
     * @return 错误码如下：
     * @retval HL_ERROR_SUCCESSFUL
     * @retval HL_ERROR_NO_INITIALIZED
     */
    int hl_p2p_deinit(void);

    /**-----App端具备的功能------**/
    /**
     * [App搜索局域网内的设备]
     *
     * @return 错误码如下：
     * @retval HL_ERROR_SUCCESSFUL
     * @retval HL_ERROR_NO_INITIALIZED
     * @retval HL_ERROR_NOT_AVAILABLE
     */
    int hl_p2p_search_lan(void);

    /**
     * [查询设备的当前状态情况]
     * 该函数是同步函数,会有一定的阻塞
     *
     * @param did     [in]  设备ID
     * @param svr     [in]  加密字串(选填,不填使用初始化时的加密字串)
     * @param dev     [out] 返回设备的状态信息
     *
     * @return 错误码如下：
     * @retval HL_ERROR_SUCCESSFUL
     * @retval HL_ERROR_NO_INITIALIZED
     * @retval HL_ERROR_TIME_OUT
     * @retval HL_ERROR_INVALID_INIT_STRING
     * @retval HL_ERROR_INVALID_ID
     * @retval HL_ERROR_INVALID_PREFIX
     * @retval HL_ERROR_FAIL_TO_ALLOCATE_MEMORY
     * @retval HL_ERROR_NOT_AVAILABLE
     */
    int hl_p2p_check_dev_state(char *did, char *svr, hl_dev_state *dev);

    /**
     * [库定时去查询设备的当前状态信息]
     * 通过cb_app_dev_state回调给上层
     *
     * @param did               [in] 设备ID
     * @param svr               [in] 加密字串(选填,不填使用初始化时的加密字串)
     * @param inter_time_sec    [in] 库中隔多久查询一次设备状态(单位是秒),传0是停止查询,范围：5~255
     * @param user              [in] 上层传入的句柄,会原值返回
     *
     * @return 错误码如下：
     * @retval HL_ERROR_SUCCESSFUL
     * @retval HL_ERROR_NO_INITIALIZED
     * @retval HL_ERROR_INVALID_INIT_STRING
     * @retval HL_ERROR_INVALID_ID
     * @retval HL_ERROR_INVALID_PREFIX
     * @retval HL_ERROR_FAIL_TO_ALLOCATE_MEMORY
     * @retval HL_ERROR_NOT_AVAILABLE
     */
    int hl_p2p_check_dev_state_async(char *did, char *svr, int inter_time_sec, void *user);

    /**
     * [向设备透传发数据]
     * 不需要连接设备,直接向设备发数据,主要用在发送少量指令数据,因为该数据通过p2p服务器转发,大数据会增加服务器带宽压力
     * 发送的结果通过cb_app_transfer_data回调
     *
     * @param did    [in] 设备ID
     * @param svr    [in] 加密字串(选填,不填使用初始化时的加密字串)
     * @param qid    [in] 发送的唯一ID(别传<0的值),当结果返回时,上层靠这个做区分
     * @param data   [in] 发送的透传数据
     * @param len    [in] 数据长度<=512
     *
     * @return 错误码如下：
     * @retval HL_ERROR_SUCCESSFUL
     * @retval HL_ERROR_NO_INITIALIZED
     * @retval HL_ERROR_INVALID_INIT_STRING
     * @retval HL_ERROR_INVALID_ID
     * @retval HL_ERROR_INVALID_PREFIX
     * @retval HL_ERROR_FAIL_TO_ALLOCATE_MEMORY
     * @retval HL_ERROR_NOT_AVAILABLE
     */
    int hl_p2p_transfer_data(char *did, char *svr, int qid, char *data, int len);

    /**
     * [并发连接]
     * 当同时连接多台设备调用connect函数时,库中做了排队连接,如果不想排队,要求同时连接,调用该函数
     * 注意：
     * 1）库中默认是进行排队连接的
     * 2）并发连接有一定的风险，当同时连接很多设备时，同时会向不同的地址发送大量udp打洞数据，容易被路由器封udp
     * 3）不推荐使用并发进行连接，并发连接如果app添加的设备量特别多，会出现突然向服务器发送大量udp数据，在有些路由器会出现封udp的情况
     *
     * @param on_off [in] 0-排队连接,1-并发连接
     *
     * @return 错误码如下：
     * @retval HL_ERROR_SUCCESSFUL
     * @retval HL_ERROR_NO_INITIALIZED
     * @retval HL_ERROR_NOT_AVAILABLE
     */
    int hl_p2p_set_parallel_connect_flag(char on_off);

    /**
     * [异步连接设备]
     * 在回调函数cb_app_connect_status里面返回连接结果,连接会马上返回
     * 注意：只能连接初始化库时使用的加密字串的集群
     *
     * @param did           [in] 设备ID
     * @param connect_mode  [in] 连接模式(hl_connect_mode)
     * @param wakeup        [in] 唤醒低功耗设备时传给设备的数据,设备端通过唤醒指令接收
     * @param wakeup_len    [in] 数据长度<=512
     * @param user          [in] 上层传入的句柄,会原值返回
     *
     * @return 错误码如下：
     * @retval >=1表示连接的session,后期都需要使用这个值
     * @retval HL_ERROR_NO_INITIALIZED
     * @retval HL_ERROR_INVALID_INIT_STRING
     * @retval HL_ERROR_INVALID_ID
     * @retval HL_ERROR_INVALID_PARAMETER
     * @retval HL_ERROR_INVALID_PREFIX
     * @retval HL_ERROR_MAX_SESSION
     * @retval HL_ERROR_FAIL_TO_ALLOCATE_MEMORY
     * @retval HL_ERROR_NOT_AVAILABLE
     */
    int hl_p2p_connect_async(char *did, char connect_mode, char *wakeup, int wakeup_len, void *user);

    /**
     * [异步连接设备]
     * 在回调函数cb_app_connect_status里面返回连接结果,连接会马上返回
     * 注意：可以连接任何集群,推荐使用
     *
     * @param did           [in] 设备ID
     * @param connect_mode  [in] 连接模式(hl_connect_mode)
     * @param svr           [in] 加密字串
     * @param wakeup        [in] 唤醒低功耗设备时传给设备的数据,设备端通过唤醒指令接收
     * @param wakeup_len    [in] 数据长度<=512
     * @param user          [in] 上层传入的句柄,会原值返回
     *
     * @return 错误码如下：
     * @retval >=1表示连接的session,后期都需要使用这个值
     * @retval HL_ERROR_NO_INITIALIZED
     * @retval HL_ERROR_INVALID_INIT_STRING
     * @retval HL_ERROR_INVALID_ID
     * @retval HL_ERROR_INVALID_PARAMETER
     * @retval HL_ERROR_INVALID_PREFIX
     * @retval HL_ERROR_MAX_SESSION
     * @retval HL_ERROR_FAIL_TO_ALLOCATE_MEMORY
     * @retval HL_ERROR_NOT_AVAILABLE
     */
    int hl_p2p_connect_by_server_async(char *did, char connect_mode, char *svr, char *wakeup, int wakeup_len, void *user);

    /**
     * [同步连接设备]
     * 该函数是阻塞函数,需要开线程连接
     * 注意：只能连接初始化库时使用的加密字串的集群
     *
     * @param did           [in] 设备ID
     * @param connect_mode  [in] 连接模式(hl_connect_mode)
     * @param wakeup        [in] 唤醒低功耗设备时传给设备的数据,设备端通过唤醒指令接收
     * @param wakeup_len    [in] 数据长度<=512
     *
     * @return 错误码如下：
     * @retval >=1表示连接的session,后期都需要使用这个值
     * @retval HL_ERROR_NO_INITIALIZED
     * @retval HL_ERROR_INVALID_INIT_STRING
     * @retval HL_ERROR_TIME_OUT
     * @retval HL_ERROR_INVALID_ID
     * @retval HL_ERROR_INVALID_PARAMETER
     * @retval HL_ERROR_INVALID_PREFIX
     * @retval HL_ERROR_MAX_SESSION
     * @retval HL_ERROR_USER_CONNECT_BREAK
     * @retval HL_ERROR_FAIL_TO_ALLOCATE_MEMORY
     * @retval HL_ERROR_NOT_AVAILABLE
     */
    int hl_p2p_connect(char *did, char connect_mode, char *wakeup, int wakeup_len);

    /**
     * [同步连接设备]
     * 该函数是阻塞函数,需要开线程连接
     * 注意：可以连接任何集群,推荐使用
     *
     * @param did           [in] 设备ID
     * @param connect_mode  [in] 连接模式(hl_connect_mode)
     * @param svr           [in] 加密字串
     * @param wakeup        [in] 唤醒低功耗设备时传给设备的数据,设备端通过唤醒指令接收
     * @param wakeup_len    [in] 数据长度<=512
     *
     * @return 错误码如下：
     * @retval >=1表示连接的session,后期都需要使用这个值
     * @retval HL_ERROR_NO_INITIALIZED
     * @retval HL_ERROR_INVALID_INIT_STRING
     * @retval HL_ERROR_TIME_OUT
     * @retval HL_ERROR_INVALID_ID
     * @retval HL_ERROR_INVALID_PARAMETER
     * @retval HL_ERROR_INVALID_PREFIX
     * @retval HL_ERROR_MAX_SESSION
     * @retval HL_ERROR_USER_CONNECT_BREAK
     * @retval HL_ERROR_FAIL_TO_ALLOCATE_MEMORY
     * @retval HL_ERROR_NOT_AVAILABLE
     */
    int hl_p2p_connect_by_server(char *did, char connect_mode, char *svr, char *wakeup, int wakeup_len);

    /**
     * [主动打断连接]
     * 用在同步连接还未结束,想主动结束连接使用
     *
     * @return 错误码如下：
     * @retval HL_ERROR_SUCCESSFUL
     * @retval HL_ERROR_NO_INITIALIZED
     * @retval HL_ERROR_NOT_AVAILABLE
     */
    int hl_p2p_connect_break(void);

    /**-----Dev端具备的功能------**/
    /**
     * [监听APP来连接]
     * 注意(推荐使用库监听App连接,可以节省上层多开线程):
     * 在 HL_LISTEN_MODE_LAN/HL_LISTEN_MODE_WAN 模式下是：阻塞函数,需要开线程监听
     * 在 HL_LISTEN_MODE_LAN_LIB_LISTEN/HL_LISTEN_MODE_WAN_LIB_LISTEN 模式下是：非阻塞函数,由库监听App连接,调用后马上返回,而且初始化库后只要调用一次
     *
     * @param did           [in] 设备ID
     * @param license       [in] 设备license
     * @param listen_mode   [in] 监听模式 hl_listen_mode
     * @param timeout_sec   [in] 监听超时时间,单位是秒,范围：60~86400,如果是长电设备该时间越长越好
     *
     * @return 错误码如下：
     * @retval >=1表示连接的session,后期都需要使用这个值
     * @retval HL_ERROR_NO_INITIALIZED
     * @retval HL_ERROR_INVALID_INIT_STRING
     * @retval HL_ERROR_TIME_OUT
     * @retval HL_ERROR_INVALID_ID
     * @retval HL_ERROR_INVALID_PREFIX
     * @retval HL_ERROR_ID_OUT_OF_DATE
     * @retval HL_ERROR_FAIL_TO_ALLOCATE_MEMORY
     * @retval HL_ERROR_IS_P2P_LISTEN_APP_CONNECT
     * @retval HL_ERROR_MAX_SESSION
     * @retval HL_ERROR_USER_LISTEN_BREAK
     * @retval HL_ERROR_NOT_AVAILABLE
     */
    int hl_p2p_listen(char *did, char *license, char listen_mode, int timeout_sec);

    /**
     * [主动打断监听]
     * 用在监听app连接还未超时,想主动结束监听时使用
     *
     * @return 错误码如下：
     * @retval HL_ERROR_SUCCESSFUL
     * @retval HL_ERROR_NO_INITIALIZED
     * @retval HL_ERROR_NOT_AVAILABLE
     */
    int hl_p2p_listen_break(void);

    /**
     * [查询设备端与P2P服务器连接状态]
     * 请在调用Listen函数10s以后再调用查询
     *
     * @param svr_login  [out] 连接的状态信息
     *
     * @return 错误码如下：
     * @retval HL_ERROR_SUCCESSFUL
     * @retval HL_ERROR_NO_INITIALIZED
     * @retval HL_ERROR_NOT_AVAILABLE
     */
    int hl_p2p_svr_login_check(hl_svr_login *svr_login);

    /**
     * [允许该设备作为转发设备]
     * 允许该设备作为转发设备,为其他设备提供转发服务,能节省转发服务器的带宽
     * 注意：默认是关闭的,需要上层自己开启,存在一定的法律风险
     *
     * @param on_off  [in] 0-关闭,1-开启
     *
     * @return 错误码如下：
     * @retval HL_ERROR_SUCCESSFUL
     * @retval HL_ERROR_NO_INITIALIZED
     * @retval HL_ERROR_NOT_AVAILABLE
     */
    int hl_p2p_share_bandwidth(char on_off);

    /**
     * [获取低功耗设备与P2P服务器保持低功耗心跳的资源信息]
     * 该函数是阻塞函数,需要开线程调用
     * 注意：
     * 1）服务器tcp端口是65525
     * 2）第一次调用该函数时ip buff里面是置空的,再次调用时,可以把上一次保存心跳的服务器ip copy到buff里面,
     *    这样再次调用该函数时,如果该服务器没有问题,会再次把改服务器ip放在第一位,这样设备就可以一直和这一台服务器保持低功耗心跳
     *    如果不传,则会根据负载均衡来控制哪个服务器ip放在第一位
     *    推荐下次调用时把上次ip copy到ip buff中,让设备一直与这一台服务器保持低功耗心跳
     * 3）当与服务器建立tcp连接成功后,向服务器发送心跳数据时,需要按照如下的格式组装数据：
     *    char buff[30]={0};
     *    buff[3]=token_len;
     *    memcpy(buff+4,token,token_len);
     *    send(sock,buff,4+token_len);
     * 4）服务器回心跳/唤醒指令数据格式：
     *    数据长(2个字节,表示后面有多少数据)+cmd(hl_wk_cmd这个里面)+wk_key(5个字节)+data(connect连接时带的wakeup数据)
     *    所以设备端要按照这个格式读取服务器返回的数据
     * 5）每次心跳服务器都会回复数据
     *
     *
     * @param did           [in]     设备ID
     * @param license       [in]     设备license
     * @param mode          [in]     mode是App与Dev自己约定的值,会写在token里面发给服务器,app可以查询到该值,该值可以用在标记当前设备处于休眠的状态：浅休眠,深休眠等等
     * @param ip            [out]    保存连接服务器IP,最多会有3个,使用逗号分隔,优先使用第一个IP保持心跳,第一个不通时再随机使用后面2个(111.23.3.44,12.12.3.44,34.44.55.66)
     * @param ip_len        [in/out] 传入表示IP buff的长度,传出表示实际有多少IP写入buff的长度,必须>=47
     * @param token         [out]    保存与服务器保持心跳时发送的token(不字符串)
     * @param token_len     [in/out] 传入表示token buff的长度,传出表示实际有多少数据写入token buff的长度,必须>=25
     * @param wk_key        [out]    保存唤醒时的库,服务器唤醒设备时,会穿该key给设备,设备端可以用在合法检测
     * @param wk_key_len    [in/out] 传入表示wk_key buff的长度,传出表示实际有多少数据写入wk_key buff的长度,必须>=5
     * @param alive_time    [out]    与服务器多久发一次心跳(token),单位是秒,固定返回60
     *
     * @return 错误码如下：
     * @retval HL_ERROR_SUCCESSFUL
     * @retval HL_ERROR_NO_INITIALIZED
     * @retval HL_ERROR_TIME_OUT
     * @retval HL_ERROR_INVALID_ID
     * @retval HL_ERROR_INVALID_PREFIX
     * @retval HL_ERROR_BUFF_LEN
     * @retval HL_ERROR_NOT_AVAILABLE
     */
    int hl_p2p_get_low_dev_token(char *did, char *license, unsigned char mode, char *ip, int *ip_len, char *token, int *token_len, char *wk_key, int *wk_key_len, int *alive_time);

    /**
     * [设置摄像机基本信息]
     * 如果要支持web端直播,需要在初始化库成功后设置这些信息
     *
     * @param camera_num         [in] 镜头数量(单目/多目等)
     * @param video_fmt          [in] 视频格式 hl_video_format
     * @param audio_fmt          [in] 音频格式 hl_audio_format
     * @param audio_channl       [in] 音频通道数
     * @param audio_sample_rate  [in] 音频采样频率
     *
     * @return 错误码如下：
     * @retval HL_ERROR_SUCCESSFUL
     * @retval HL_ERROR_NO_INITIALIZED
     * @retval HL_ERROR_INVALID_PARAMETER
     * @retval HL_ERROR_NOT_AVAILABLE
     */
    int hl_p2p_set_camera_info(char camera_num, char video_fmt, char audio_fmt, char audio_channl, int audio_sample_rate);

    /**
     * [发送Webrtc流]
     * 设备端收到cb_dev_webrtc_live() status=1时开启直播,0时关闭直播
     * 该数据流会发给服务器,web端通过webrtc/rtmp/rtsp等从服务器获取该流
     * 注意：
     * 1）库中不会对数据加密,如有需要上层应用自己加密
     * 2）调用该函数前,要先调用 hl_p2p_webrtc_check_buffer()查询本地对应通道还有多少数据未发送出去
     * 3）当是发送音视频数据时 data是: hl_webrtc_header+data(音视频裸数据),非音视频通道不需要加 hl_webrtc_header
     *
     * @param wid       [in] webrtc唯一ID,回调里面返回的
     * @param channel   [in] 0-命令通道(优先发送),1-视频流通道,2-音频流通道,3-数据通道
     * @param data      [in] 要发送的数据
     * @param len       [in] 数据长度
     *
     * @return 错误码如下：
     * @retval >0发送了多少数据到库里面
     * @retval HL_ERROR_NO_INITIALIZED
     * @retval HL_ERROR_INVALID_PARAMETER
     * @retval HL_ERROR_DATA_MAX_2M
     * @retval HL_ERROR_BUFF_FULL_LOCAL
     * @retval HL_ERROR_DID_UNSUPPORT_WEBRTC
     * @retval HL_ERROR_WEBRTC_LIVE_INVALID
     * @retval HL_ERROR_NOT_AVAILABLE
     */
    int hl_p2p_webrtc_push(int wid, char channel, char *data, int len);

    /**
     * [查询音视频流还有多少数据未发送出去]
     * 表示本地还有多少数据未发送出现,在调用hl_p2p_webrtc_push()前先调用该函数查询
     * 当数据>=512K或其他自己设定的值后,需要延时10ms再查询,直到<512K时才调用hl_p2p_webrtc_push()下发新数据
     * 如果长时间发送不出去,需要适当考虑丢帧和降低码率,已确保发送视频流畅
     *
     * @param wid       [in] webrtc唯一ID,回调里面返回的
     * @param channel   [in] 0-命令通道(优先发送),1-视频流通道,2-音频流通道,3-数据通道
     * @param len       [out] 对应流本地还有多少数据未发送出去
     *
     * @return 错误码如下：
     * @retval HL_ERROR_SUCCESSFUL
     * @retval HL_ERROR_NO_INITIALIZED
     * @retval HL_ERROR_INVALID_PARAMETER
     * @retval HL_ERROR_BUFF_FULL_LOCAL
     * @retval HL_ERROR_DID_UNSUPPORT_WEBRTC
     * @retval HL_ERROR_WEBRTC_LIVE_INVALID
     * @retval HL_ERROR_NOT_AVAILABLE
     */
    int hl_p2p_webrtc_check_buffer(int wid, char channel, int *len);

    /**
     * [清理对应流的本地还未发送的缓存数据]
     * 如果想把发送到库,但是库还未发送到网络的数据清理掉,可以调用该函数
     *
     * @param wid       [in] webrtc唯一ID,回调里面返回的
     * @param channel   [in] 0-命令通道(优先发送),1-视频流通道,2-音频流通道,3-数据通道
     *
     * @return 错误码如下：
     * @retval >=0表示清理了多少还未发送的缓存数据
     * @retval HL_ERROR_NO_INITIALIZED
     * @retval HL_ERROR_INVALID_PARAMETER
     * @retval HL_ERROR_DID_UNSUPPORT_WEBRTC
     * @retval HL_ERROR_WEBRTC_LIVE_INVALID
     * @retval HL_ERROR_NOT_AVAILABLE
     */
    int hl_p2p_webrtc_clear_buffer(int wid, char channel);

    /**
     * [关闭Webrtc流]
     *
     * @param wid  [in] webrtc唯一ID,回调里面返回的
     *
     * @return 错误码如下：
     * @retval >=0表示清理了多少还未发送的缓存数据
     * @retval HL_ERROR_NO_INITIALIZED
     * @retval HL_ERROR_DID_UNSUPPORT_WEBRTC
     * @retval HL_ERROR_WEBRTC_LIVE_INVALID
     * @retval HL_ERROR_NOT_AVAILABLE
     */
    int hl_p2p_webrtc_close(int wid);

    /**
     * [回复App端的透传数据]
     * 当App端向设备发了透传数据,如果设备想回复数据调用该函数
     *
     * @param aid   [in] 回调函数里面的原值
     * @param seq   [in] 回调函数里面的原值
     * @param data  [in] 需要发给app端的数据
     * @param len   [in] 数据长度<=512
     *
     * @return 错误码如下：
     * @retval HL_ERROR_SUCCESSFUL
     * @retval HL_ERROR_NO_INITIALIZED
     * @retval HL_ERROR_INVALID_PARAMETER
     * @retval HL_ERROR_FAIL
     * @retval HL_ERROR_FAIL_TO_ALLOCATE_MEMORY
     * @retval HL_ERROR_NOT_AVAILABLE
     */
    int hl_p2p_reply_transfer_data(int aid, int seq, char *data, int len);

    /**
     * [设置转发服务器的域名]
     * 当设备是4G定向卡时,需要设置转发服务器的域名到库里面进行解析
     * 目的是解决转发服务器ip不需要增加到卡商白名单依然可以与这个服务器通讯
     *
     * @param domain     [in] 域名字符串,就使用一个域名绑定多个转发服务器ip
     * @param domain_len [in] 域名数据长度
     *
     * @return 错误码如下：
     * @retval HL_ERROR_SUCCESSFUL
     * @retval HL_ERROR_NO_INITIALIZED
     * @retval HL_ERROR_INVALID_PARAMETER
     * @retval HL_ERROR_FAIL
     * @retval HL_ERROR_FAIL_TO_ALLOCATE_MEMORY
     * @retval HL_ERROR_NOT_AVAILABLE
     */
    int hl_p2p_set_svr_domain(char *domain, int domain_len);

    /**
     * [增加域名解析的服务器IP]
     * 上层设置指定DNS域名服务器,库解析域名时会向这些服务器发请求
     * 注意：不设置库里也有默认的域名服务器IP,默认的如下：
     * 223.5.5.5
     * 223.6.6.6
     * 114.114.114.114
     * 8.8.8.8
     *
     * @param ip   [in] DNS服务器的IP
     * @param idx  [in] 序号：添加时从0开始
     *
     * @return 错误码如下：
     * @retval HL_ERROR_SUCCESSFUL
     * @retval HL_ERROR_NO_INITIALIZED
     * @retval HL_ERROR_INVALID_PARAMETER
     * @retval HL_ERROR_FAIL
     * @retval HL_ERROR_NOT_AVAILABLE
     */
    int hl_p2p_add_dns_svr(char *ip, int idx);

    /**
     * [设置P2P域名解析得到的IP]
     * 如果是上层要求主动去解析P2P域名,库会通过cb_dev_need_parse_domain()告诉上层需要去解析哪些域名
     * 上层解析完成域名得到IP后,只需要把P2P域名解析的IP设置给库里
     *
     * @param ip   [in] 解析P2P域名得到的IP
     * @param idx  [in] 序号：从0开始
     *
     * @return 错误码如下：
     * @retval HL_ERROR_SUCCESSFUL
     * @retval HL_ERROR_NO_INITIALIZED
     * @retval HL_ERROR_INVALID_PARAMETER
     * @retval HL_ERROR_FAIL
     * @retval HL_ERROR_NOT_AVAILABLE
     */
    int hl_p2p_set_p2p_domain_ip(char *ip, int idx);

    /**
     * [告诉库里面当前设备是否有网络]
     * 这个主要用在低功耗设备,当设备给主控断网 不断电的情况下,在断网后调用该函数 告诉库没有网络了
     * 库会开始1s向服务器发起一次请求,当来网后库能第一时间与服务器连接上,能更快的接收app连接
     * 所以在给主控只断网不断电的情况下,P2P Listen保存原样,这样能更快接收app连接
     *
     * @param on_off   [in] 0-告诉库当前没有网络,1-告诉库来网络了
     *
     * @return 错误码如下：
     * @retval HL_ERROR_SUCCESSFUL
     * @retval HL_ERROR_NO_INITIALIZED
     * @retval HL_ERROR_NOT_AVAILABLE
     */
    int hl_p2p_network_ok(char on_off);

    /**
     * [修改设备端是否接收App局域网搜索]
     * 注意：默认是允许App局域网搜索该设备
     *
     * @param on_off   [in] 0-禁止局域网搜索,1-允许局域网搜索
     *
     * @return 错误码如下：
     * @retval HL_ERROR_SUCCESSFUL
     * @retval HL_ERROR_NO_INITIALIZED
     * @retval HL_ERROR_NOT_AVAILABLE
     */
    int hl_p2p_allow_lan_search(char on_off);

    /**-----App与Dev端都具备的功能------**/
    /**
     * [检查连接状态]
     *
     * @param session   [in] 连接的session句柄
     *
     * @return 错误码如下：
     * @retval >0 表示连接状态：hl_connect_status
     * @retval HL_ERROR_NO_INITIALIZED
     * @retval HL_ERROR_INVALID_SESSION_HANDLE
     * @retval HL_ERROR_SESSION_CLOSE_REMOTE
     * @retval HL_ERROR_SESSION_CLOSE_TIMEOUT
     * @retval HL_ERROR_SESSION_CLOSE_CALLED
     */
    int hl_p2p_check(int session);

    /**
     * [主动关闭连接]
     * 如果库里面还有数据未发送出去,会等待数据发送完后再关闭连接
     * 所以该函数可能有时会有一定的阻塞时间
     *
     * @param session   [in] 连接的session句柄
     *
     * @return 错误码如下：
     * @retval HL_ERROR_SUCCESSFUL
     * @retval HL_ERROR_NO_INITIALIZED
     * @retval HL_ERROR_INVALID_SESSION_HANDLE
     * @retval HL_ERROR_SESSION_CLOSE_REMOTE
     * @retval HL_ERROR_SESSION_CLOSE_TIMEOUT
     * @retval HL_ERROR_SESSION_CLOSE_CALLED
     */
    int hl_p2p_close(int session);

    /**
     * [强制关闭连接]
     * 不管库里面是否有数据未发送完,都会直接关闭,未发送的数据直接丢掉
     *
     * @param session   [in] 连接的session句柄
     *
     * @return 错误码如下：
     * @retval HL_ERROR_SUCCESSFUL
     * @retval HL_ERROR_NO_INITIALIZED
     * @retval HL_ERROR_INVALID_SESSION_HANDLE
     * @retval HL_ERROR_SESSION_CLOSE_REMOTE
     * @retval HL_ERROR_SESSION_CLOSE_TIMEOUT
     * @retval HL_ERROR_SESSION_CLOSE_CALLED
     */
    int hl_p2p_force_close(int session);

    /**
     * [获取库中当前有多少个连接]
     *
     * @return 错误码如下：
     * @retval >0 表示有多少个连接
     * @retval HL_ERROR_NO_INITIALIZED
     */
    int hl_p2p_get_session_count(void);

    /**
     * [读取对方发过来的数据]
     * 该函数是阻塞函数,需要开线程监听
     * 该函数读数据像udp那样,会一次把对方write()的数据全部读出,如果buff小于对方write的数据,则会丢掉多余的数据
     * 所以buff需要设置成对方可能write一次最大的值,特别是在循环读视频数据时
     *
     * @param session       [in]     连接的session句柄
     * @param channel       [in]     读哪一个通道的数据,范围：0~channel_max-1
     * @param data          [out]    接收数据的buff
     * @param len           [in/out] 数据长度,传入表示buff大小,传出表示读到多少数据
     * @param timeout_ms    [in]     超时时间,单位毫秒,传0表示用不超时直到读到数据返回
     *
     * @return 错误码如下：
     * @retval HL_ERROR_SUCCESSFUL
     * @retval HL_ERROR_NO_INITIALIZED
     * @retval HL_ERROR_TIME_OUT
     * @retval HL_ERROR_INVALID_PARAMETER
     * @retval HL_ERROR_INVALID_SESSION_HANDLE
     * @retval HL_ERROR_SESSION_CLOSE_REMOTE
     * @retval HL_ERROR_SESSION_CLOSE_TIMEOUT
     * @retval HL_ERROR_SESSION_CLOSE_CALLED
     * @retval HL_ERROR_DATA_LEN_ZERO
     * @retval HL_ERROR_IS_P2P_CALLBACK_DATA
     */
    int hl_p2p_read_udp(int session, char channel, char *data, int *len, int timeout_ms);

    /**
     * [读取对方发过来的数据]
     * 该函数是阻塞函数,需要开线程监听
     * 该函数读数据像tcp那样,上层指定一次性读取多少数据,读到数据或超时返回
     *
     * @param session       [in]     连接的session句柄
     * @param channel       [in]     读哪一个通道的数据,范围：0~channel_max-1
     * @param data          [out]    接收数据的buff
     * @param len           [in/out] 数据长度,传入表示要读取多少数据,传出表示读到多少数据
     * @param timeout_ms    [in]     超时时间,单位毫秒,传0表示用不超时直到读到数据返回
     *
     * @return 错误码如下：
     * @retval HL_ERROR_SUCCESSFUL
     * @retval HL_ERROR_NO_INITIALIZED
     * @retval HL_ERROR_TIME_OUT
     * @retval HL_ERROR_INVALID_PARAMETER
     * @retval HL_ERROR_INVALID_SESSION_HANDLE
     * @retval HL_ERROR_SESSION_CLOSE_REMOTE
     * @retval HL_ERROR_SESSION_CLOSE_TIMEOUT
     * @retval HL_ERROR_SESSION_CLOSE_CALLED
     * @retval HL_ERROR_DATA_LEN_ZERO
     * @retval HL_ERROR_IS_P2P_CALLBACK_DATA
     */
    int hl_p2p_read_tcp(int session, char channel, char *data, int *len, int timeout_ms);

    /**
     * [主动断开读取]
     * 当读取对应通道的函数阻塞未结束时,想主动结束读取调用该函数
     *
     * @param session       [in] 连接的session句柄
     * @param channel       [in] 读哪一个通道的数据,范围：0~channel_max-1
     *
     * @return 错误码如下：
     * @retval HL_ERROR_SUCCESSFUL
     * @retval HL_ERROR_NO_INITIALIZED
     * @retval HL_ERROR_TIME_OUT
     * @retval HL_ERROR_INVALID_PARAMETER
     * @retval HL_ERROR_INVALID_SESSION_HANDLE
     * @retval HL_ERROR_SESSION_CLOSE_REMOTE
     * @retval HL_ERROR_SESSION_CLOSE_TIMEOUT
     * @retval HL_ERROR_SESSION_CLOSE_CALLED
     */
    int hl_p2p_read_break(int session, char channel);

    /**
     * [向对方发送数据]
     * 一次最大发送不能超过2M数据,推荐发送视频时一帧一次性发送(一般一帧数据不会太大)
     * 注意：
     * 1）本地每个通道的最大缓存也是2M数据
     * 2）通道0是密码通道,库里面会对该通道数据默认加密,并且优先发送该通道数据
     * 3）当发送大数据时(音视频/文件),请不要加密,不然会降低效率,如要做加密上层自己对数据进行加密
     * 4）如果是发大数据(音视频/文件下载),每次调用write函数前,先调用hl_p2p_check_buffer()函数查看对应通道本地还有多少数据未发送出去,
     *    设置一个值比如比如512K,当大于该值时需要延时10ms再check_buff直到小于该值,然后再调用write函数
     *
     * @param session       [in] 连接的session句柄
     * @param channel       [in] 向哪个通道发数据,范围：0~channel_max-1
     * @param data          [in] 发送的数据
     * @param len           [in] 数据长度
     * @param is_encrypt    [in] 是否对该次发送的数据加密,0-不加密,1-加密
     *
     * @return 错误码如下：
     * @retval >0发送了多少数据到库中
     * @retval HL_ERROR_NO_INITIALIZED
     * @retval HL_ERROR_INVALID_PARAMETER
     * @retval HL_ERROR_INVALID_SESSION_HANDLE
     * @retval HL_ERROR_SESSION_CLOSE_REMOTE
     * @retval HL_ERROR_SESSION_CLOSE_TIMEOUT
     * @retval HL_ERROR_SESSION_CLOSE_CALLED
     * @retval HL_ERROR_DATA_LEN_ZERO
     * @retval HL_ERROR_DATA_MAX_2M
     * @retval HL_ERROR_BUFF_FULL_LOCAL
     * @retval HL_ERROR_FAIL_TO_ALLOCATE_MEMORY
     */
    int hl_p2p_write(int session, char channel, char *data, int len, char is_encrypt);

    /**
     * [检查本地对应通道有多少数据]
     * 检查本地对应通道有多少数据还未发送出去和有多少数据可以读取
     *
     * @param session   [in]  连接的session句柄
     * @param channel   [in]  向哪个通道发数据,范围：0~channel_max-1
     * @param read_len  [out] 获取该通道本地有多少数据可以读取
     * @param write_len [out] 获取该通道本地还有多少数据未发送出去
     *
     * @return 错误码如下：
     * @retval HL_ERROR_SUCCESSFUL
     * @retval HL_ERROR_NO_INITIALIZED
     * @retval HL_ERROR_INVALID_PARAMETER
     * @retval HL_ERROR_INVALID_SESSION_HANDLE
     * @retval HL_ERROR_SESSION_CLOSE_REMOTE
     * @retval HL_ERROR_SESSION_CLOSE_TIMEOUT
     * @retval HL_ERROR_SESSION_CLOSE_CALLED
     * @retval HL_ERROR_BUFF_FULL_LOCAL
     */
    int hl_p2p_check_buffer(int session, char channel, int *read_len, int *write_len);

    /**
     * [删除本地对应通道的缓存数据]
     *
     * @param session   [in] 连接的session句柄
     * @param channel   [in] 向哪个通道发数据,范围：0~channel_max-1
     * @param is_read   [in] 1-删除还未读取的缓存数据,0-删除还未发送出去的缓存数据
     *
     * @return 错误码如下：
     * @retval HL_ERROR_SUCCESSFUL
     * @retval HL_ERROR_NO_INITIALIZED
     * @retval HL_ERROR_INVALID_PARAMETER
     * @retval HL_ERROR_INVALID_SESSION_HANDLE
     * @retval HL_ERROR_SESSION_CLOSE_REMOTE
     * @retval HL_ERROR_SESSION_CLOSE_TIMEOUT
     * @retval HL_ERROR_SESSION_CLOSE_CALLED
     */
    int hl_p2p_clear_buffer(int session, char channel, char is_read);

    /**
     * [是否允许在默认网卡连接不了网络时,使用其他网卡尝试]
     *
     * @param type   [in] 0-查询当前使用什么网卡,1-设置,当type=1时,返回0-当前使用默认网卡,1-使用其他网卡
     * @param on_off [in] type=1时该值起作用,0-禁止使用其他网卡,1-允许使用其他网卡
     *
     * @return 错误码如下：
     * @retval HL_ERROR_SUCCESSFUL
     * @retval HL_ERROR_NO_INITIALIZED
     */
    int hl_p2p_other_network_card_conn(char type, char on_off);

    /**
     * [库可以开始回调数据]
     * 如果在初始化库时是要求库回调数据
     * a)app连接不是异步连接
     * b)设备端listen不是库listen
     * 那么在连接成功或者listen到app连接后,需要调用该函数,让库可以开始回调数据
     * 这样做是为了：上层先得到session，然后还有对应session的数据回调上来
     *
     * @param session   [in] 连接的session句柄
     *
     * @return 错误码如下：
     * @retval HL_ERROR_SUCCESSFUL
     * @retval HL_ERROR_NO_INITIALIZED
     * @retval HL_ERROR_INVALID_SESSION_HANDLE
     */
    int hl_p2p_lib_cb_start(int session);

    /********=======================下面是加解密接口,采用AES加密,提供给外层使用========================================***********/
    /**
     * [对数据进行加密]
     * 数据加密后会变成字符串
     *
     * @param src      [in] 需要加密的数据
     * @param src_len  [in] 数据长度
     * @param dest     [in] 保存加密后的数据buff
     * @param dest_len [in] buff数据长度,必须dest_len>=src_len*2
     *
     * @return 错误码如下：
     * @retval HL_ERROR_SUCCESSFUL
     * @retval HL_ERROR_NO_INITIALIZED
     * @retval HL_ERROR_BUFF_LEN
     */
    int hl_encrypt(char *src, int src_len, char *dest, int *dest_len);

    /**
     * [对数据进行解密]
     *
     * @param src      [in] 需要解密的数据
     * @param src_len  [in] 数据长度
     * @param dest     [in] 保存解密后的数据buff
     * @param dest_len [in] buff数据长度,必须dest_len>=src_len/2
     *
     * @return 错误码如下：
     * @retval HL_ERROR_SUCCESSFUL
     * @retval HL_ERROR_NO_INITIALIZED
     * @retval HL_ERROR_BUFF_LEN
     * @retval HL_ERROR_DATA_INVALID
     */
    int hl_decrypt(char *src, int src_len, char *dest, int *dest_len);

    /********=======================下面是云端接口========================================***********/

    /**批量烧录ID**/
    int hl_cloud_did_get(int code, char *svr, char *num, char *mac);
    int hl_cloud_did_result(int code, char *svr, char *num, char *did, char *license);

    int hl_cloud_upload(int code, char *path, char type, char *ali_file_name, char *ali_endpoint, char *ali_bucket_name, char *ali_access_key_id, char *ali_access_key_secret);
    int hl_cloud_download(int code, char *path, char type, char *ali_file_name, char *ali_endpoint, char *ali_bucket_name, char *ali_access_key_id, char *ali_access_key_secret);
    int hl_cloud_file_add(int code, char *svr, char type, char *ali_file_name, char *ali_endpoint, char *ali_bucket_name, char *ali_access_key_id, char *ali_access_key_secret);

    /**报警推送**/
    int hl_cloud_push(int code, char *svr, unsigned char type, char *content, char *ali_pic_file_name, char *ali_vid_file_name, char *ali_endpoint, char *ali_bucket_name, char *ali_access_key_id, char *ali_access_key_secret);

    /********=======================下面是音视频接口========================================***********/

    /**初始化**/
    int hl_codec_init(int cid, char video_format, char audio_format, char audio_channel, int audio_sample);
    int hl_codec_deinit(int cid);

    /**编解码**/
    int hl_codec_video_decode(int cid, char *src_data, int s_offset, int src_len, char *dest_data, int d_offset, int *dest_len, char key, int *width, int *height);
    int hl_codec_video_encode(int cid, char *src_data, int s_offset, int src_len, char *dest_data, int d_offset, int *dest_len);
    int hl_codec_audio_decode(int cid, char *src_data, int s_offset, int src_len, char *dest_data, int d_offset, int *dest_len);
    int hl_codec_audio_encode(int cid, char *src_data, int s_offset, int src_len, char *dest_data, int d_offset, int *dest_len);

    /**抓图**/
    int hl_codec_take_picture(char *path, char *data, int offset, int data_len, int width, int height);

    /**录mp4**/
    int hl_codec_record_start(int cid, char *path, int width, int height);
    int hl_codec_record_stop(int cid);
    int hl_codec_record_write_video(int cid, char *data, int offset, int len, char key);
    int hl_codec_record_write_audio(int cid, char *data, int offset, int len);

    /********=======================下面是类似尚云接口,修改函数前缀便可以替换========================================***********/
    typedef struct
    {
        char bFlagInternet;     /**Internet Reachable? 1: YES, 0: NO**/
        char bFlagHostResolved; /**P2P Server IP resolved? 1: YES, 0: NO**/
        char bFlagServerHello;  /**P2P Server Hello? 1: YES, 0: NO**/
        char NAT_Type;          /**NAT type, 0: Unknow, 1: IP-Restricted Cone type,   2: Port-Restricted Cone type, 3: Symmetric**/
        char MyLanIP[20];       /**My LAN IP. If (bFlagInternet==0) || (bFlagHostResolved==0) || (bFlagServerHello==0), MyLanIP will be "0.0.0.0"**/
        char MyWanIP[20];       /**My Wan IP. If (bFlagInternet==0) || (bFlagHostResolved==0) || (bFlagServerHello==0), MyWanIP will be "0.0.0.0"**/
    } st_HLP2P_NetInfo;

    typedef struct
    {
        int Skt;                  /**Sockfd**/
        char RemoteAddr[20];      /**Remote IP:Port**/
        char MyLocalAddr[20];     /**My Local IP:Port**/
        char MyWanAddr[20];       /**My Wan IP:Port**/
        unsigned int ConnectTime; /**Connection build in ? Sec Before**/
        char DID[24];             /**Device ID**/
        char bCorD;               /**I am Client or Device, 0: Client, 1: Device**/
        char bMode;               /**hl_connect_status**/
        char Reserved[2];
    } st_HLP2P_Session;

    /**-----App与Dev端都具备的功能------**/
    /**
     * [设置库日志开关](库默认是关闭的)
     * 请在初始化库之前设置
     *
     * @param Type   [in] 日志类型:一个或多个 HL_LOG_TYPE_MGT|HL_LOG_TYPE_SESS
     * @param Level  [in] 暂时填0
     * @param Open   [in] 0-关闭,1-开启
     *
     * @return 错误码如下：
     * @retval HL_ERROR_SUCCESSFUL
     * @retval HL_ERROR_INVALID_PARAMETER
     */
    int HLP2P_SetLogLevel(char Type, char Level, char Open);

    /**
     * [获取库版本号]
     *
     * @return 返回库编译的日志
     * @retval 比如：20250808
     */
    int HLP2P_GetAPIVersion(void);

    /**
     * [获取库信息]
     *
     * @return 字符串信息
     */
    char *HLP2P_GetAPIInformation(void);

    /**
     * [设置库回调函数]
     * 请在初始化库之前设置
     *
     * @param cb   [in] 回调函数
     *
     * @return 错误码如下：
     * @retval HL_ERROR_SUCCESSFUL
     * @retval HL_ERROR_INVALID_PARAMETER
     */
    int HLP2P_SetCallback(hl_p2p_cb *CB);

    /**
     * [初始化库]
     *
     * @param ServerString  [in] 加密字符串
     *
     * @return 错误码如下：
     * @retval HL_ERROR_SUCCESSFUL
     * @retval HL_ERROR_ALREADY_INITIALIZED
     * @retval HL_ERROR_INVALID_INIT_STRING
     * @retval HL_ERROR_FAIL_TO_CREATE_THREAD
     * @retval HL_ERROR_FAIL_TO_ALLOCATE_MEMORY
     * @retval HL_ERROR_FAIL
     */
    int HLP2P_Initialize(char *ServerString);

    /**
     * [注销库]
     * 在给主控断电前记得注销库
     * 如果只给主控断网,不需要注销库,这个时候调用 HLP2P_NetworkOk(0)告诉库没有网络 是比较好的选择
     *
     * @return 错误码如下：
     * @retval HL_ERROR_SUCCESSFUL
     * @retval HL_ERROR_NO_INITIALIZED
     */
    int HLP2P_DeInitialize(void);

    /**-----App端具备的功能------**/

    /**
     * [App搜索局域网内的设备]
     *
     * @return 错误码如下：
     * @retval HL_ERROR_SUCCESSFUL
     * @retval HL_ERROR_NO_INITIALIZED
     * @retval HL_ERROR_NOT_AVAILABLE
     */
    int HLP2P_SearchLan(void);

    /**
     * [查询设备的当前状态情况]
     * 该函数是同步函数,会有一定的阻塞
     *
     * @param TargetID     [in]  设备ID
     * @param ServerString [in]  加密字串(选填,不填使用初始化时的加密字串)
     * @param SDev         [out] 返回设备的状态信息
     *
     * @return 错误码如下：
     * @retval HL_ERROR_SUCCESSFUL
     * @retval HL_ERROR_NO_INITIALIZED
     * @retval HL_ERROR_INVALID_INIT_STRING
     * @retval HL_ERROR_INVALID_ID
     * @retval HL_ERROR_INVALID_PREFIX
     * @retval HL_ERROR_FAIL_TO_ALLOCATE_MEMORY
     * @retval HL_ERROR_NOT_AVAILABLE
     */
    int HLP2P_Check_DevState(char *TargetID, char *ServerString, hl_dev_state *SDev);

    /**
     * [库定时去查询设备的当前状态信息]
     * 通过cb_app_dev_state回调给上层
     *
     * @param TargetID     [in]  设备ID
     * @param ServerString [in]  加密字串(选填,不填使用初始化时的加密字串)
     * @param InterTimeSec [in] 库中隔多久查询一次设备状态(单位是秒),传0是停止查询,范围：5~255
     * @param user         [in] 上层传入的句柄,会原值返回
     *
     * @return 错误码如下：
     * @retval HL_ERROR_SUCCESSFUL
     * @retval HL_ERROR_NO_INITIALIZED
     * @retval HL_ERROR_INVALID_INIT_STRING
     * @retval HL_ERROR_INVALID_ID
     * @retval HL_ERROR_INVALID_PREFIX
     * @retval HL_ERROR_FAIL_TO_ALLOCATE_MEMORY
     * @retval HL_ERROR_NOT_AVAILABLE
     */
    int HLP2P_Check_DevState_Async(char *TargetID, char *ServerString, int InterTimeSec, void *user);

    /**
     * [向设备透传发数据]
     * 不需要连接设备,直接向设备发数据
     * 发送的结果通过cb_app_transfer_data回调
     *
     * @param TargetID     [in] 设备ID
     * @param ServerString [in] 加密字串(选填,不填使用初始化时的加密字串)
     * @param Seq          [in] 发送的唯一ID(别传<0的值),当结果返回时,上层靠这个做区分
     * @param DataBuf      [in] 发送的透传数据
     * @param DataSize     [in] 数据长度<=512
     *
     * @return 错误码如下：
     * @retval HL_ERROR_SUCCESSFUL
     * @retval HL_ERROR_NO_INITIALIZED
     * @retval HL_ERROR_INVALID_INIT_STRING
     * @retval HL_ERROR_INVALID_ID
     * @retval HL_ERROR_INVALID_PREFIX
     * @retval HL_ERROR_FAIL_TO_ALLOCATE_MEMORY
     * @retval HL_ERROR_NOT_AVAILABLE
     */
    int HLP2P_TransferData(char *TargetID, char *ServerString, int Seq, char *DataBuf, int DataSize);

    /**
     * [并发连接]
     * 当同时连接多台设备调用connect函数时,库中做了排队连接,如果不想排队,要求同时连接,调用该函数
     * 注意：
     * 1）库中默认是进行排队连接的
     * 2）并发连接有一定的风险，当同时连接很多设备时，同时会向不同的地址发送大量udp打洞数据，容易被路由器封udp
     * 3）推荐不适应并发进行连接
     *
     * @param on_off [in] 0-排队连接,1-并发连接
     *
     * @return 错误码如下：
     * @retval HL_ERROR_SUCCESSFUL
     * @retval HL_ERROR_NO_INITIALIZED
     * @retval HL_ERROR_NOT_AVAILABLE
     */
    int HLP2P_SetParallelConnectFlag(char OnOff);

    /**
     * [异步连接设备]
     * 在回调函数cb_app_connect_status里面返回连接结果,连接会马上返回
     * 注意：只能连接初始化库时使用的加密字串的集群
     *
     * @param TargetID     [in] 设备ID
     * @param ConnectMode  [in] 连接模式(hl_connect_mode)
     * @param UDPPort      [in] 填0
     * @param user         [in] 上层传入的句柄,会原值返回
     *
     * @return 错误码如下：
     * @retval >=1表示连接的session,后期都需要使用这个值
     * @retval HL_ERROR_NO_INITIALIZED
     * @retval HL_ERROR_INVALID_INIT_STRING
     * @retval HL_ERROR_INVALID_ID
     * @retval HL_ERROR_INVALID_PARAMETER
     * @retval HL_ERROR_INVALID_PREFIX
     * @retval HL_ERROR_MAX_SESSION
     * @retval HL_ERROR_FAIL_TO_ALLOCATE_MEMORY
     * @retval HL_ERROR_NOT_AVAILABLE
     */
    int HLP2P_Connect_Async(char *TargetID, char ConnectMode, unsigned short UDPPort, void *User);

    /**
     * [异步连接设备]
     * 在回调函数cb_app_connect_status里面返回连接结果,连接会马上返回
     * 注意：可以连接任何集群,推荐使用
     *
     * @param TargetID     [in] 设备ID
     * @param ConnectMode  [in] 连接模式(hl_connect_mode)
     * @param UDPPort      [in] 填0
     * @param ServerString [in] 加密字串
     * @param user         [in] 上层传入的句柄,会原值返回
     *
     * @return 错误码如下：
     * @retval >=1表示连接的session,后期都需要使用这个值
     * @retval HL_ERROR_NO_INITIALIZED
     * @retval HL_ERROR_INVALID_INIT_STRING
     * @retval HL_ERROR_INVALID_ID
     * @retval HL_ERROR_INVALID_PARAMETER
     * @retval HL_ERROR_INVALID_PREFIX
     * @retval HL_ERROR_MAX_SESSION
     * @retval HL_ERROR_FAIL_TO_ALLOCATE_MEMORY
     * @retval HL_ERROR_NOT_AVAILABLE
     */
    int HLP2P_ConnectByServer_Async(char *TargetID, char ConnectMode, unsigned short UDPPort, char *ServerString, void *User);

    /**
     * [同步连接设备]
     * 该函数是阻塞函数,需要开线程连接
     * 注意：只能连接初始化库时使用的加密字串的集群
     *
     * @param TargetID     [in] 设备ID
     * @param ConnectMode  [in] 连接模式(hl_connect_mode)
     * @param UDPPort      [in] 填0
     *
     * @return 错误码如下：
     * @retval >=1表示连接的session,后期都需要使用这个值
     * @retval HL_ERROR_NO_INITIALIZED
     * @retval HL_ERROR_INVALID_INIT_STRING
     * @retval HL_ERROR_TIME_OUT
     * @retval HL_ERROR_INVALID_ID
     * @retval HL_ERROR_INVALID_PARAMETER
     * @retval HL_ERROR_INVALID_PREFIX
     * @retval HL_ERROR_MAX_SESSION
     * @retval HL_ERROR_USER_CONNECT_BREAK
     * @retval HL_ERROR_FAIL_TO_ALLOCATE_MEMORY
     * @retval HL_ERROR_NOT_AVAILABLE
     */
    int HLP2P_Connect(char *TargetID, char ConnectMode, unsigned short UDPPort);

    /**
     * [同步连接设备]
     * 该函数是阻塞函数,需要开线程连接
     * 注意：可以连接任何集群,推荐使用
     *
     * @param TargetID     [in] 设备ID
     * @param ConnectMode  [in] 连接模式(hl_connect_mode)
     * @param UDPPort      [in] 填0
     * @param ServerString [in] 加密字串
     *
     * @return 错误码如下：
     * @retval >=1表示连接的session,后期都需要使用这个值
     * @retval HL_ERROR_NO_INITIALIZED
     * @retval HL_ERROR_INVALID_INIT_STRING
     * @retval HL_ERROR_TIME_OUT
     * @retval HL_ERROR_INVALID_ID
     * @retval HL_ERROR_INVALID_PARAMETER
     * @retval HL_ERROR_INVALID_PREFIX
     * @retval HL_ERROR_MAX_SESSION
     * @retval HL_ERROR_USER_CONNECT_BREAK
     * @retval HL_ERROR_FAIL_TO_ALLOCATE_MEMORY
     * @retval HL_ERROR_NOT_AVAILABLE
     */
    int HLP2P_ConnectByServer(char *TargetID, char ConnectMode, unsigned short UDPPort, char *ServerString);

    /**
     * [主动打断连接]
     * 用在同步连接还未结束,想主动结束连接使用
     *
     * @return 错误码如下：
     * @retval HL_ERROR_SUCCESSFUL
     * @retval HL_ERROR_NO_INITIALIZED
     * @retval HL_ERROR_NOT_AVAILABLE
     */
    int HLP2P_Connect_Break(void);

    /**-----Dev端具备的功能------**/
    /**
     * [监听APP来连接]
     * 注意(推荐使用库监听App连接,可以节省上层多开线程):
     * 在 HL_LISTEN_MODE_LAN/HL_LISTEN_MODE_WAN 模式下是：阻塞函数,需要开线程监听
     * 在 HL_LISTEN_MODE_LAN_LIB_LISTEN/HL_LISTEN_MODE_WAN_LIB_LISTEN 模式下是：非阻塞函数,由库监听App连接,调用后马上返回,而且初始化库后只要调用一次
     *
     * @param TargetID    [in] 设备ID
     * @param TimeOutSec  [in] 监听超时时间,单位是秒,范围：60~86400,如果是长电设备该时间越长越好
     * @param UDPPort     [in] 填0
     * @param ListenMode  [in] 监听模式 hl_listen_mode
     * @param APILicense  [in] 设备license
     *
     * @return 错误码如下：
     * @retval >=1表示连接的session,后期都需要使用这个值
     * @retval HL_ERROR_NO_INITIALIZED
     * @retval HL_ERROR_INVALID_INIT_STRING
     * @retval HL_ERROR_TIME_OUT
     * @retval HL_ERROR_INVALID_ID
     * @retval HL_ERROR_INVALID_PREFIX
     * @retval HL_ERROR_ID_OUT_OF_DATE
     * @retval HL_ERROR_FAIL_TO_ALLOCATE_MEMORY
     * @retval HL_ERROR_IS_P2P_LISTEN_APP_CONNECT
     * @retval HL_ERROR_MAX_SESSION
     * @retval HL_ERROR_USER_LISTEN_BREAK
     * @retval HL_ERROR_NOT_AVAILABLE
     */
    int HLP2P_Listen(char *TargetID, int TimeOutSec, unsigned short UDPPort, char ListenMode, char *APILicense);

    /**
     * [主动打断监听]
     * 用在监听app连接还未超时,想主动结束监听时使用
     *
     * @return 错误码如下：
     * @retval HL_ERROR_SUCCESSFUL
     * @retval HL_ERROR_NO_INITIALIZED
     * @retval HL_ERROR_NOT_AVAILABLE
     */
    int HLP2P_Listen_Break(void);

    /**
     * [查询设备端与P2P服务器连接状态]
     * 请在调用Listen函数10s以后再调用查询
     *
     * @param SvrLogin  [out] 连接的状态信息
     *
     * @return 错误码如下：
     * @retval HL_ERROR_SUCCESSFUL
     * @retval HL_ERROR_NO_INITIALIZED
     * @retval HL_ERROR_NOT_AVAILABLE
     */
    int HLP2P_LoginStatus_Check(hl_svr_login *SvrLogin);

    /**
     * [允许该设备作为转发设备]
     * 允许该设备作为转发设备,为其他设备提供转发服务,能节省转发服务器的带宽
     * 注意：默认是关闭的,需要上层自己开启,存在一定的法律风险
     *
     * @param bOnOff  [in] 0-关闭,1-开启
     *
     * @return 错误码如下：
     * @retval HL_ERROR_SUCCESSFUL
     * @retval HL_ERROR_NO_INITIALIZED
     * @retval HL_ERROR_NOT_AVAILABLE
     */
    int HLP2P_Share_Bandwidth(char bOnOff);

    /**
     * [获取低功耗设备与P2P服务器保持低功耗心跳的资源信息]
     * 该函数是阻塞函数,需要开线程调用
     * 注意：
     * 1）服务器tcp端口是65525
     * 2）第一次调用该函数时ip buff里面是置空的,再次调用时,可以把上一次保存心跳的服务器ip copy到buff里面,
     *    这样再次调用该函数时,如果该服务器没有问题,会再次把改服务器ip放在第一位,这样设备就可以一直和这一台服务器保持低功耗心跳
     *    如果不传,则会根据负载均衡来控制哪个服务器ip放在第一位
     *    推荐下次调用时把上次ip copy到ip buff中,让设备一直与这一台服务器保持低功耗心跳
     * 3）当与服务器建立tcp连接成功后,向服务器发送心跳数据时,需要按照如下的格式组装数据：
     *    char buff[30]={0};
     *    buff[3]=token_len;
     *    memcpy(buff+4,token,token_len);
     *    send(sock,buff,4+token_len);
     * 4）服务器回心跳/唤醒指令数据格式：
     *    数据长(2个字节,表示后面有多少数据)+cmd(hl_wk_cmd这个里面)+wk_key(5个字节)+data(connect连接时带的wakeup数据)
     *    所以设备端要按照这个格式读取服务器返回的数据
     * 5）每次心跳服务器都会回复数据
     *
     *
     * @param TargetID      [in]     设备ID
     * @param APILicense    [in]     设备license
     * @param Mode          [in]     mode是App与Dev自己约定的值,会写在token里面发给服务器,app可以查询到该值,该值可以用在标记当前设备处于休眠的状态：浅休眠,深休眠等等
     * @param IP            [out]    保存连接服务器IP,最多会有3个,使用逗号分隔,优先使用第一个IP保持心跳,第一个不通时再随机使用后面2个(111.23.3.44,12.12.3.44,34.44.55.66)
     * @param IPLen         [in/out] 传入表示IP buff的长度,传出表示实际有多少IP写入buff的长度,必须>=47
     * @param Token         [out]    保存与服务器保持心跳时发送的token(不字符串)
     * @param TokenLen      [in/out] 传入表示token buff的长度,传出表示实际有多少数据写入token buff的长度,必须>=25
     * @param WKKey         [out]    保存唤醒时的库,服务器唤醒设备时,会穿该key给设备,设备端可以用在合法检测
     * @param WKKeyLen      [in/out] 传入表示wk_key buff的长度,传出表示实际有多少数据写入wk_key buff的长度,必须>=5
     * @param AliveTime     [out]    与服务器多久发一次心跳(token),单位是秒,固定返回60
     *
     * @return 错误码如下：
     * @retval HL_ERROR_SUCCESSFUL
     * @retval HL_ERROR_NO_INITIALIZED
     * @retval HL_ERROR_TIME_OUT
     * @retval HL_ERROR_INVALID_ID
     * @retval HL_ERROR_INVALID_PREFIX
     * @retval HL_ERROR_BUFF_LEN
     * @retval HL_ERROR_NOT_AVAILABLE
     */
    int HLP2P_GetLowDevToken(char *TargetID, char *APILicense, unsigned char Mode, char *IP, int *IPLen, char *Token, int *TokenLen, char *WKKey, int *WKKeyLen, int *AliveTime);

    /**
     * [设置摄像机基本信息]
     * 如果要支持web端直播,需要在初始化库成功后设置这些信息
     *
     * @param camera_num         [in] 镜头数量(单目/多目等)
     * @param video_fmt          [in] 视频格式 hl_video_format
     * @param audio_fmt          [in] 音频格式 hl_audio_format
     * @param audio_channel      [in] 音频通道数
     * @param audio_sample_rate  [in] 音频采样频率
     *
     * @return 错误码如下：
     * @retval HL_ERROR_SUCCESSFUL
     * @retval HL_ERROR_NO_INITIALIZED
     * @retval HL_ERROR_INVALID_PARAMETER
     * @retval HL_ERROR_NOT_AVAILABLE
     */
    int HLP2P_SetCameraInfo(char camera_num, char video_fmt, char audio_fmt, char audio_channel, int audio_sample_rate);

    /**
     * [发送Webrtc流]
     * 设备端收到cb_dev_webrtc_live() status=1时开启直播,0时关闭直播
     * 该数据流会发给服务器,web端通过webrtc/rtmp/rtsp等从服务器获取该流
     * 注意：
     * 1）库中不会对数据加密,如有需要上层应用自己加密
     * 2）调用该函数前,要先调用 HLP2P_Webrtc_CheckBuffer()查询本地对应通道还有多少数据未发送出去
     * 3）当是发送音视频数据时 data是: hl_webrtc_header+data(音视频裸数据),非音视频通道不需要加 hl_webrtc_header
     *
     * @param Wid       [in] webrtc唯一ID,回调里面返回的
     * @param Channel   [in] 0-命令通道(优先发送),1-视频流通道,2-音频流通道,3-数据通道
     * @param DataBuf   [in] 要发送的数据
     * @param DataSize  [in] 数据长度
     *
     * @return 错误码如下：
     * @retval >0发送了多少数据到库里面
     * @retval HL_ERROR_NO_INITIALIZED
     * @retval HL_ERROR_INVALID_PARAMETER
     * @retval HL_ERROR_DATA_MAX_2M
     * @retval HL_ERROR_BUFF_FULL_LOCAL
     * @retval HL_ERROR_DID_UNSUPPORT_WEBRTC
     * @retval HL_ERROR_WEBRTC_LIVE_INVALID
     * @retval HL_ERROR_NOT_AVAILABLE
     */
    int HLP2P_Webrtc_Push(int Wid, char Channel, char *DataBuf, int DataSize);

    /**
     * [查询音视频流还有多少数据未发送出去]
     * 表示本地还有多少数据未发送出现,在调用 HLP2P_Webrtc_Push()前先调用该函数查询
     * 当数据>=512K或其他自己设定的值后,需要延时10ms再查询,直到<512K时才调用 HLP2P_Webrtc_Push()下发新数据
     * 如果长时间发送不出去,需要适当考虑丢帧和降低码率,已确保发送视频流畅
     *
     * @param Wid       [in] webrtc唯一ID,回调里面返回的
     * @param Channel   [in] 0-命令通道(优先发送),1-视频流通道,2-音频流通道,3-数据通道
     * @param Len       [out] 对应流本地还有多少数据未发送出去
     *
     * @return 错误码如下：
     * @retval HL_ERROR_SUCCESSFUL
     * @retval HL_ERROR_NO_INITIALIZED
     * @retval HL_ERROR_INVALID_PARAMETER
     * @retval HL_ERROR_BUFF_FULL_LOCAL
     * @retval HL_ERROR_DID_UNSUPPORT_WEBRTC
     * @retval HL_ERROR_WEBRTC_LIVE_INVALID
     * @retval HL_ERROR_NOT_AVAILABLE
     */
    int HLP2P_Webrtc_CheckBuffer(int Wid, char Channel, int *Len);

    /**
     * [清理对应流的本地还未发送的缓存数据]
     * 如果想把发送到库,但是库还未发送到网络的数据清理掉,可以调用该函数
     *
     * @param Wid       [in] webrtc唯一ID,回调里面返回的
     * @param Channel   [in] 0-命令通道(优先发送),1-视频流通道,2-音频流通道,3-数据通道
     *
     * @return 错误码如下：
     * @retval >=0表示清理了多少还未发送的缓存数据
     * @retval HL_ERROR_NO_INITIALIZED
     * @retval HL_ERROR_INVALID_PARAMETER
     * @retval HL_ERROR_DID_UNSUPPORT_WEBRTC
     * @retval HL_ERROR_WEBRTC_LIVE_INVALID
     * @retval HL_ERROR_NOT_AVAILABLE
     */
    int HLP2P_Webrtc_ClearBuffer(int Wid, char Channel);

    /**
     * [关闭Webrtc流]
     *
     * @param Wid  [in] webrtc唯一ID,回调里面返回的
     *
     * @return 错误码如下：
     * @retval >=0表示清理了多少还未发送的缓存数据
     * @retval HL_ERROR_NO_INITIALIZED
     * @retval HL_ERROR_DID_UNSUPPORT_WEBRTC
     * @retval HL_ERROR_WEBRTC_LIVE_INVALID
     * @retval HL_ERROR_NOT_AVAILABLE
     */
    int HLP2P_Webrtc_Close(int Wid);

    /**
     * [回复App端的透传数据]
     * 当App端向设备发了透传数据,如果设备想回复数据调用该函数
     *
     * @param Aid      [in] 回调函数里面的原值
     * @param Seq      [in] 回调函数里面的原值
     * @param DataBuf  [in] 需要发给app端的数据
     * @param DataSize [in] 数据长度<=512
     *
     * @return 错误码如下：
     * @retval HL_ERROR_SUCCESSFUL
     * @retval HL_ERROR_NO_INITIALIZED
     * @retval HL_ERROR_INVALID_PARAMETER
     * @retval HL_ERROR_FAIL
     * @retval HL_ERROR_FAIL_TO_ALLOCATE_MEMORY
     * @retval HL_ERROR_NOT_AVAILABLE
     */
    int HLP2P_ReplyTransferData(int Aid, int Seq, char *DataBuf, int DataSize);

    /**
     * [设置转发服务器的域名]
     * 当设备是4G定向卡时,需要设置转发服务器的域名到库里面进行解析
     * 目的是解决转发服务器ip不需要增加到卡商白名单依然可以与这个服务器通讯
     *
     * @param Domain     [in] 域名字符串,就使用一个域名绑定多个转发服务器ip
     * @param DomainLen  [in] 域名数据长度
     *
     * @return 错误码如下：
     * @retval HL_ERROR_SUCCESSFUL
     * @retval HL_ERROR_NO_INITIALIZED
     * @retval HL_ERROR_INVALID_PARAMETER
     * @retval HL_ERROR_FAIL
     * @retval HL_ERROR_FAIL_TO_ALLOCATE_MEMORY
     * @retval HL_ERROR_NOT_AVAILABLE
     */
    int HLP2P_SetSvrDomain(char *Domain, int DomainLen);

    /**
     * [增加域名解析的服务器IP]
     * 上层设置指定DNS域名服务器,库解析域名时会向这些服务器发请求
     * 注意：不设置库里也有默认的域名服务器IP,默认的如下：
     * 223.5.5.5
     * 223.6.6.6
     * 114.114.114.114
     * 8.8.8.8
     *
     * @param IP   [in] DNS服务器的IP
     * @param Idx  [in] 序号：添加时从0开始
     *
     * @return 错误码如下：
     * @retval HL_ERROR_SUCCESSFUL
     * @retval HL_ERROR_NO_INITIALIZED
     * @retval HL_ERROR_INVALID_PARAMETER
     * @retval HL_ERROR_FAIL
     * @retval HL_ERROR_NOT_AVAILABLE
     */
    int HLP2P_AddDNSSvr(char *IP, int Idx);

    /**
     * [设置P2P域名解析得到的IP]
     * 如果是上层要求主动去解析P2P域名,库会通过cb_dev_need_parse_domain()告诉上层需要去解析哪些域名
     * 上层解析完成域名得到IP后,只需要把P2P域名解析的IP设置给库里
     *
     * @param IP   [in] 解析P2P域名得到的IP
     * @param Idx  [in] 序号：从0开始
     *
     * @return 错误码如下：
     * @retval HL_ERROR_SUCCESSFUL
     * @retval HL_ERROR_NO_INITIALIZED
     * @retval HL_ERROR_INVALID_PARAMETER
     * @retval HL_ERROR_FAIL
     * @retval HL_ERROR_NOT_AVAILABLE
     */
    int HLP2P_SetP2PDomainIP(char *IP, int Idx);

    /**
     * [告诉库里面当前设备是否有网络]
     * 这个主要用在低功耗设备,当设备给主控断网 不断电的情况下,在断网后调用该函数 告诉库没有网络了
     * 库会开始1s向服务器发起一次请求,当来网后库能第一时间与服务器连接上,能更快的接收app连接
     * 所以在给主控只断网不断电的情况下,P2P Listen保存原样,这样能更快接收app连接
     *
     * @param OnOff   [in] 0-告诉库当前没有网络,1-告诉库来网络了
     *
     * @return 错误码如下：
     * @retval HL_ERROR_SUCCESSFUL
     * @retval HL_ERROR_NO_INITIALIZED
     * @retval HL_ERROR_NOT_AVAILABLE
     */
    int HLP2P_NetworkOk(char OnOff);

    /**
     * [修改设备端是否接收App局域网搜索]
     * 注意：默认是允许App局域网搜索该设备
     *
     * @param OnOff   [in] 0-禁止局域网搜索,1-允许局域网搜索
     *
     * @return 错误码如下：
     * @retval HL_ERROR_SUCCESSFUL
     * @retval HL_ERROR_NO_INITIALIZED
     * @retval HL_ERROR_NOT_AVAILABLE
     */
    int HLP2P_AllowLanSearch(char OnOff);

    /**-----App与Dev端都具备的功能------**/
    /**
     * [修改库支持最大连接数和通道数]
     * 注意：SessionMax 默认和最大值都800,ChannelMax 默认和最大值都8
     *
     * @param SessionMax   [in] 最大连接数据,默认和最大值是800
     * @param ChannelMax   [in] 每一个连接的最大通道数,默认和最大值是800
     *
     * @return 错误码如下：
     * @retval HL_ERROR_SUCCESSFUL
     * @retval HL_ERROR_NO_INITIALIZED
     * @retval HL_ERROR_NOT_AVAILABLE
     */
    int HLP2P_SetSessionMax(int SessionMax, char ChannelMax);

    /**
     * [检查连接状态]
     *
     * @param SessionHandle   [in]  连接的session句柄
     * @param SInfo           [out] 返回连接状态信息
     *
     * @return 错误码如下：
     * @retval HL_ERROR_SUCCESSFUL
     * @retval HL_ERROR_NO_INITIALIZED
     * @retval HL_ERROR_INVALID_PARAMETER
     * @retval HL_ERROR_INVALID_SESSION_HANDLE
     */
    int HLP2P_Check(int SessionHandle, st_HLP2P_Session *SInfo);

    /**
     * [主动关闭连接]
     * 如果库里面还有数据未发送出去,会等待数据发送完后再关闭连接
     * 所以该函数可能有时会有一定的阻塞时间
     *
     * @param SessionHandle   [in] 连接的session句柄
     *
     * @return 错误码如下：
     * @retval HL_ERROR_SUCCESSFUL
     * @retval HL_ERROR_NO_INITIALIZED
     * @retval HL_ERROR_INVALID_SESSION_HANDLE
     * @retval HL_ERROR_SESSION_CLOSE_REMOTE
     * @retval HL_ERROR_SESSION_CLOSE_TIMEOUT
     * @retval HL_ERROR_SESSION_CLOSE_CALLED
     */
    int HLP2P_Close(int SessionHandle);

    /**
     * [强制关闭连接]
     * 不管库里面是否有数据未发送完,都会直接关闭,未发送的数据直接丢掉
     *
     * @param SessionHandle   [in] 连接的session句柄
     *
     * @return 错误码如下：
     * @retval HL_ERROR_SUCCESSFUL
     * @retval HL_ERROR_NO_INITIALIZED
     * @retval HL_ERROR_INVALID_SESSION_HANDLE
     * @retval HL_ERROR_SESSION_CLOSE_REMOTE
     * @retval HL_ERROR_SESSION_CLOSE_TIMEOUT
     * @retval HL_ERROR_SESSION_CLOSE_CALLED
     */
    int HLP2P_ForceClose(int SessionHandle);

    /**
     * [获取库中当前有多少个连接]
     *
     * @return 错误码如下：
     * @retval >0 表示有多少个连接
     * @retval HL_ERROR_NO_INITIALIZED
     */
    int HLP2P_Get_SessionCount(void);

    /**
     * [读取对方发过来的数据]
     * 该函数是阻塞函数,需要开线程监听
     * 该函数读数据像tcp那样,上层指定一次性读取多少数据,读到数据或超时返回
     *
     * @param SessionHandle     [in]     连接的session句柄
     * @param Channel           [in]     读哪一个通道的数据,范围：0~channel_max-1
     * @param DataBuf           [out]    接收数据的buff
     * @param DataSize          [in/out] 数据长度,传入表示要读取多少数据,传出表示读到多少数据
     * @param TimeOut_ms        [in]     超时时间,单位毫秒,传0表示用不超时直到读到数据返回
     *
     * @return 错误码如下：
     * @retval HL_ERROR_SUCCESSFUL
     * @retval HL_ERROR_NO_INITIALIZED
     * @retval HL_ERROR_TIME_OUT
     * @retval HL_ERROR_INVALID_PARAMETER
     * @retval HL_ERROR_INVALID_SESSION_HANDLE
     * @retval HL_ERROR_SESSION_CLOSE_REMOTE
     * @retval HL_ERROR_SESSION_CLOSE_TIMEOUT
     * @retval HL_ERROR_SESSION_CLOSE_CALLED
     * @retval HL_ERROR_DATA_LEN_ZERO
     * @retval HL_ERROR_IS_P2P_CALLBACK_DATA
     */
    int HLP2P_Read(int SessionHandle, char Channel, char *DataBuf, int *DataSize, int TimeOut_ms);

    /**
     * [主动断开读取]
     * 当读取对应通道的函数阻塞未结束时,想主动结束读取调用该函数
     *
     * @param SessionHandle     [in] 连接的session句柄
     * @param Channel           [in] 读哪一个通道的数据,范围：0~channel_max-1
     *
     * @return 错误码如下：
     * @retval HL_ERROR_SUCCESSFUL
     * @retval HL_ERROR_NO_INITIALIZED
     * @retval HL_ERROR_TIME_OUT
     * @retval HL_ERROR_INVALID_PARAMETER
     * @retval HL_ERROR_INVALID_SESSION_HANDLE
     * @retval HL_ERROR_SESSION_CLOSE_REMOTE
     * @retval HL_ERROR_SESSION_CLOSE_TIMEOUT
     * @retval HL_ERROR_SESSION_CLOSE_CALLED
     */
    int HLP2P_ReadBreak(int SessionHandle, char Channel);

    /**
     * [向对方发送数据]
     * 一次最大发送不能超过2M数据,推荐发送视频时一帧一次性发送(一般一帧数据不会太大)
     * 注意：
     * 1）本地每个通道的最大缓存也是2M数据
     * 2）通道0是密码通道,库里面会对该通道数据默认加密,并且优先发送该通道数据
     * 3）如果是发大数据(音视频/文件下载),每次调用write函数前,先调用 HLP2P_Check_Buffer()函数查看对应通道本地还有多少数据未发送出去,
     *    设置一个值比如比如512K,当大于该值时需要延时10ms再check_buff直到小于该值,然后再调用write函数
     *
     * @param SessionHandle    [in] 连接的session句柄
     * @param Channel          [in] 向哪个通道发数据,范围：0~channel_max-1
     * @param DataBuf          [in] 发送的数据
     * @param DataSizeToWrite  [in] 数据长度
     *
     * @return 错误码如下：
     * @retval >0发送了多少数据到库中
     * @retval HL_ERROR_NO_INITIALIZED
     * @retval HL_ERROR_INVALID_PARAMETER
     * @retval HL_ERROR_INVALID_SESSION_HANDLE
     * @retval HL_ERROR_SESSION_CLOSE_REMOTE
     * @retval HL_ERROR_SESSION_CLOSE_TIMEOUT
     * @retval HL_ERROR_SESSION_CLOSE_CALLED
     * @retval HL_ERROR_DATA_LEN_ZERO
     * @retval HL_ERROR_DATA_MAX_2M
     * @retval HL_ERROR_BUFF_FULL_LOCAL
     * @retval HL_ERROR_FAIL_TO_ALLOCATE_MEMORY
     */
    int HLP2P_Write(int SessionHandle, char Channel, char *DataBuf, int DataSizeToWrite);

    /**
     * [检查本地对应通道有多少数据]
     * 检查本地对应通道有多少数据还未发送出去和有多少数据可以读取
     *
     * @param SessionHandle     [in]  连接的session句柄
     * @param Channel           [in]  向哪个通道发数据,范围：0~channel_max-1
     * @param WriteSize         [out] 获取该通道本地还有多少数据未发送出去
     * @param ReadSize          [out] 获取该通道本地有多少数据可以读取
     *
     * @return 错误码如下：
     * @retval HL_ERROR_SUCCESSFUL
     * @retval HL_ERROR_NO_INITIALIZED
     * @retval HL_ERROR_INVALID_PARAMETER
     * @retval HL_ERROR_INVALID_SESSION_HANDLE
     * @retval HL_ERROR_SESSION_CLOSE_REMOTE
     * @retval HL_ERROR_SESSION_CLOSE_TIMEOUT
     * @retval HL_ERROR_SESSION_CLOSE_CALLED
     * @retval HL_ERROR_BUFF_FULL_LOCAL
     */
    int HLP2P_Check_Buffer(int SessionHandle, char Channel, int *WriteSize, int *ReadSize);

    /**
     * [删除本地对应通道的缓存数据]
     *
     * @param SessionHandle   [in] 连接的session句柄
     * @param Channel         [in] 向哪个通道发数据,范围：0~channel_max-1
     * @param IsRead          [in] 1-删除还未读取的缓存数据,0-删除还未发送出去的缓存数据
     *
     * @return 错误码如下：
     * @retval HL_ERROR_SUCCESSFUL
     * @retval HL_ERROR_NO_INITIALIZED
     * @retval HL_ERROR_INVALID_PARAMETER
     * @retval HL_ERROR_INVALID_SESSION_HANDLE
     * @retval HL_ERROR_SESSION_CLOSE_REMOTE
     * @retval HL_ERROR_SESSION_CLOSE_TIMEOUT
     * @retval HL_ERROR_SESSION_CLOSE_CALLED
     */
    int HLP2P_Clear_Buffer(int SessionHandle, char Channel, char IsRead);

    /**
     * [是否允许在默认网卡连接不了网络时,使用其他网卡尝试]
     *
     * @param Type   [in] 0-查询当前使用什么网卡,1-设置,当type=1时,返回0-当前使用默认网卡,1-使用其他网卡
     * @param OnOff  [in] type=1时该值起作用,0-禁止使用其他网卡,1-允许使用其他网卡
     *
     * @return 错误码如下：
     * @retval >=0
     * @retval HL_ERROR_NO_INITIALIZED
     */
    int HLP2P_OtherNetworkCardConn(char Type, char OnOff);

    /**-----下面函数未实现------**/
    int HLP2P_Enable_SmartDevice(char bOnOff);                                                              /**未实现,不需要用**/
    int HLP2P_NetworkDetect(st_HLP2P_NetInfo *NetInfo, unsigned short UDPPort);                             /**未实现,不需要用**/
    int HLP2P_NetworkDetectByServer(st_HLP2P_NetInfo *NetInfo, unsigned short UDPPort, char *ServerString); /**未实现,不需要用**/
    int HLP2P_QueryDID(char *DeviceName, char *DID, int DIDBufSize);                                        /**未实现,不需要用**/
    int HLP2P_PktSend(int SessionHandle, char Channel, char *PktBuf, int PktSize);                          /**未实现,不需要用**/
    int HLP2P_PktRecv(int SessionHandle, char Channel, char *PktBuf, int *PktSize, int TimeOutMs);          /**未实现,不需要用**/


#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* __cplusplus */

#endif